package com.example.utils;

import com.jcraft.jsch.*;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Random;
import java.util.UUID;

public class FileUtil {
    static String username = "root";
    static String password = "Love873973409";
    static String host = "8.130.34.162";
    static int port = 22;

    // 创建JSch对象
    static JSch jSch = new JSch();
    static Session jSchSession = null;
    static ChannelSftp chSftp = null;


    //本地路径
    private static final String  basePath = "src/main/resources/static/pictures/";//项目路径+在项目中创建一个文件夹

    static public ChannelSftp getChSftp(){
        try {
            // 根据主机账号、ip、端口获取一个Session对象
            jSchSession = jSch.getSession(username, host, port);

            //存放主机密码
            jSchSession.setPassword(password);
            // 去掉首次连接确认
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            jSchSession.setConfig(config);
            // 超时连接时间为8秒
            jSchSession.setTimeout(8000);
            // 进行连接
            jSchSession.connect();
            // 打开SFTP通道
            chSftp = (ChannelSftp)jSchSession.openChannel("sftp");
            // 建立SFTP通道的连接
            chSftp.connect();
            // 设置编码格式
            chSftp.setFilenameEncoding("UTF-8");
            return chSftp;
        } catch (JSchException e) {
            throw new RuntimeException(e);
        } catch (SftpException e) {
            throw new RuntimeException(e);
        }
    }

    static public String close(ChannelSftp chSftp){
        // 关闭sftpChannel
        if (chSftp != null && chSftp.isConnected()) {
            chSftp.quit();
            jSchSession.disconnect();
            return "关闭成功";
        }else {
            return "关闭失败！";
        }
    }

    static public String upload(MultipartFile file) throws IOException, SftpException {     //path是指保存在哪个目录，目录名与数据表名相同
        //服务器绝对地址
        String serverBathPath = "/home/GymSys/pictures/";
        //        获取文件原始名字
        String originalFilename = file.getOriginalFilename();
//        获取文件名后缀
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
//        生成随机文件名字
        String filename = UUID.randomUUID().toString();

        String url = basePath+filename + suffix;

        //服务器中文件地址
        String serverUrl = serverBathPath+filename + suffix;

        //      2. 判断转存的目录是否存在
//         File既可以代表一个目录，又可以代表一个文件
        File dir = new File(basePath);
//         判断当前目录是否存在
        if (!dir.exists()){
//          不存在的时候进行创建
            dir.mkdirs();
        }

        //      转存临时文件到指定的位置  参数是一个URL路径
        file.transferTo(new File(url));

        //接下来将图片发送到服务器

        ChannelSftp chSftp = FileUtil.getChSftp();
        //第一个参数是本地项目中文件的位置，第二个参数是服务器中保存文件的路径
        chSftp.put(url,serverUrl);
        //关闭连接
        FileUtil.close(chSftp);

        //删除临时存放的文件
        File temp = new File(url);
        boolean delete = temp.delete();
        if(!delete){
            throw new IOException("删除临时文件失败");
        }

        //返回上传的请求，参数为服务器中图片的地址
        return "/download?filePath="+serverUrl;

    }


    //前端网页会同时发送很多的图片请求，使用synchronized关键字保证一次请求处理结束后才处理下一个，否则输入流会被过早关闭
    public static synchronized void download(String filePath, HttpServletResponse response)  throws SftpException, IOException{
        //先将文件从服务器下载到本地
        ChannelSftp chSftp = FileUtil.getChSftp();

        //保存到本地后的随机名字
        String filename = UUID.randomUUID().toString();

        //第一个参数是服务器中图片的地址
        try{
            chSftp.get(filePath,basePath+ filename +".jpeg");//从服务器中下载保存到本地，因为最后会删除所以命名不重要
        }catch (Exception e){
            e.printStackTrace();
        }
        //返回至前端
        //      0. 设置文件格式
        response.setContentType("image/jpeg");
        //      1. 输入流，通过输入流读取文件内容
        FileInputStream fileInputStream = new FileInputStream(new File(basePath +filename+ ".jpeg"));

//      2. response输出流，将文件写回浏览器
        ServletOutputStream outputStream = response.getOutputStream();

        int len = 0;
        byte[] bytes = new byte[1024];
        while ((len = fileInputStream.read(bytes)) != -1) {
            outputStream.write(bytes, 0, len);
            outputStream.flush();
        }

        //      3.关闭流
        outputStream.close();
        fileInputStream.close();
        //删除临时存放的文件
        File temp = new File(basePath+filename+".jpeg");
        boolean delete = temp.delete();
        if(!delete){
            throw new IOException("删除临时文件失败");
        }

    }


}
